package com.nxn.core.web.tag;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.nxn.core.service.DataLoaderService;
import com.nxn.core.utils.CacheListener;

/**
 * This is a JSP custom tag uses to render the linked JavaScript & StyleSheet
 * resources HTML.
 * 
 * A configuration file named as "assets.xml" will be loaded when the class
 * begin to load. The element named as "mode" could be used to control whether
 * to run as debug mode or not.
 * 
 * If we set to debug mode, all JavaScript & StyleSheet resources will be linked
 * as separated bundles, otherwise a combined file will be replaced.
 * 
 * @author Michael Zhang
 */
@SuppressWarnings("serial")
public class Resource extends TagSupport {
	private static final Logger LOGGER = Logger.getLogger(Resource.class);

	private String name = null;
	
	/**
	 * Sets the name of the custom tag attribute, it will be set internally.
	 * 
	 * @param name
	 *            The name.
	 */
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int doStartTag() throws JspException {
		StringBuffer out = new StringBuffer();
		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
		ServletContext servletContext = pageContext.getServletContext();
		
		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
		DataLoaderService dataLoader = (DataLoaderService) wac.getBean("dataLoaderService");
		
		String prefix = request.getContextPath();
		Group group = dataLoader.initWebAssets(CacheListener.xmlFileName);

		if (group != null) {

			if (FileRepository.isDebug()) {
				Bundles bundles = group.getBundles();

				for (String asset : bundles.getStyleSheets()) {
					appendStyleSheet(out, prefix, asset);
				}

				for (String asset : bundles.getJavaScripts()) {
					appendJavaScript(out, prefix, asset);
				}

			} else {
				Releases merges = group.getReleases();

				appendStyleSheet(out, prefix, merges.getStyleSheet());
				appendJavaScript(out, prefix, merges.getJavaScript());
			}
		}

		try {
			pageContext.getOut().write(out.toString());

		} catch (Exception ex) {
			LOGGER.error("Failed to write HTML: " + out, ex);

			throw new JspException(ex);
		}

		return SKIP_BODY;
	}

	private void appendJavaScript(StringBuffer source, String prefix, String file) {

		if (StringUtils.isNotBlank(file)) {
			source.append("<script type=\"text/javascript\" src=\"" + prefix + "/" + file + "\"></script>\n");
		}
	}

	private void appendStyleSheet(StringBuffer source, String prefix, String file) {

		if (StringUtils.isNotBlank(file)) {
			source.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + prefix + "/" + file + "\" />\n");
		}
	}
}
